﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;

namespace SPHelper
{
    public class List
    {
		public static bool IsExist(SPWeb web, string listName)
		{
			bool isExist = false;
			try
			{
				// init
				if (web == null) { throw new Exception("SPWeb passed is null"); }
				if (string.IsNullOrEmpty(listName)) { throw new Exception("List name passed is null"); }


				SPList list = null;
				list = web.Lists.TryGetList(listName);
				if (list != null) { isExist = true; }
			}
			catch (Exception ex)
			{
				Log.WriteError("et5heytketkjerj", ex);
			}
			return isExist;
		}

		/// <summary>
		/// Get a list by guid
		/// </summary>
		/// <param name="web"></param>
		/// <param name="listId"></param>
		/// <returns></returns>
		public static SPList GetListById(SPWeb web, Guid listId)
		{
			SPList list = null;
			try
			{
				// init
				if (web == null) { web = Web.GetWeb(); }
				if (web == null) { throw new Exception("SPWeb passed is null and couldn't get from SPContext"); }
				if (listId == null || listId == Guid.Empty) { throw new Exception("listId GUID passed is invalid"); }


				if (web.Lists.Count > 0)
				{
					foreach (SPList l in web.Lists)
					{
						if (l.ID == listId) { list = l; break; }
					}
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("yjfyukfdhser6", ex);
				list = null;
			}
			return list;
		}

		public static SPList GetListById(Guid listId)
		{
			return GetListById(null, listId);
		}


		/// <summary>
		/// Get a list by list title
		/// </summary>
		/// <param name="web"></param>
		/// <param name="title"></param>
		/// <returns></returns>
		public static SPList GetListByTitle(SPWeb web, string title)
		{
			SPList list = null;
			try
			{
				// init
				if (web == null) { web = Web.GetWeb(); }
				if (web == null) { throw new Exception("SPWeb passed is null and couldn't get from SPContext"); }
				if (string.IsNullOrEmpty(title)) { throw new Exception("list title passed is invalid"); }
				title = title.Trim();

				if (web.Lists.Count > 0)
				{
					list = web.Lists.TryGetList(title);
				}
			}
			catch (Exception ex)
			{
				Log.WriteError("8t7otu8ifytfrtr76t", ex);
				list = null;
			}
			return list;
		}

		public static SPList GetListByTitle(string title)
		{
			return GetListByTitle(null, title);
		}

		/// <summary>
		/// Get SPList from the passed url
		/// </summary>
		/// <param name="web">The web for which the list exists in. If null, will use SPContext web. If that failed, it will try to parse the url to get the list specific SPWeb.</param>
		/// <param name="url">List url</param>
		/// <returns></returns>
		public static SPList GetListByUrl(SPWeb web, string url)
		{
			SPList list = null;
			try
			{
				// init
				if (string.IsNullOrEmpty(url)) { throw new Exception("list url passed is null"); }
				if (web == null) { web = Web.GetWeb(); }
				if (web == null) { throw new Exception("Failed to get SPWeb from SPContext or the passed url"); }

				// get the list (1st try)
				try { list = web.GetList(url); } catch { }

				// 2nd try
				if (list == null)
				{
					// get web from url
					web = SPHelper.Web.GetWebByUrl(url);

					// get list again
					list = web.GetList(url);
				}

				if (list == null) { throw new Exception("Failed to get SPList using url"); }
			}
			catch (Exception ex)
			{
				// Log.WriteError("t7i5t7kdujtsdrsdrrsdt", ex, "url: " + url + ", web: " + ((web != null) ? web.Url : ""));
				list = null;
			}
			return list;
		}

		/// <summary>
		/// Get list using passed url
		/// </summary>
		/// <param name="absoluteUrl"></param>
		/// <returns></returns>
		public static SPList GetListByUrl(string url)
		{
			return GetListByUrl(null, url);
		}
		




		/// <summary>
		/// Creates a new SharePoint List, and saves to database
		/// </summary>
		/// <param name="web"></param>
		/// <param name="title"></param>
		/// <param name="description"></param>
		/// <param name="listType"></param>
		/// <param name="isEnableAttachments"></param>
		/// <param name="isEnableFolderCreation"></param>
		/// <param name="isOnQuickLaunch"></param>
		/// <param name="isContentTypesEnabled">Allow custom content types on this list?</param>
		/// <param name="isDeleteIfListAlreadyExists">Delete list if already exists, otherwise, throw error</param>
		/// <returns></returns>
		public static SPList CreateList(SPWeb web, string title, string description, SPListTemplateType listType,
			bool isEnableAttachments, bool isEnableFolderCreation, bool isOnQuickLaunch, bool isContentTypesEnabled,
			bool isDeleteIfListAlreadyExists)
		{
			SPList newList = null;
			try
			{
				// init
				if (web == null) { throw new Exception("SPWeb passed is null"); }
				if (string.IsNullOrEmpty(title)) { throw new Exception("Title passed is null"); }


				// delete list if it alread exists
				if (web.Lists.Count > 0)
				{
					SPList duplicateList = web.Lists.TryGetList(title);
					if (duplicateList != null)
					{
						if (isDeleteIfListAlreadyExists) { duplicateList.Delete(); }
						else { throw new Exception("Error, duplicate list with name: \"" + title + "\" already exists"); }
					}
				}

				// create new list
				Guid listId = web.Lists.Add(title, description, listType);

				// update list properties
				newList = web.Lists[listId];
				newList.EnableAttachments = isEnableAttachments;
				newList.EnableFolderCreation = isEnableFolderCreation;
				newList.OnQuickLaunch = isOnQuickLaunch;
				newList.ContentTypesEnabled = isContentTypesEnabled;
				newList.Update();
			}
			catch (Exception ex)
			{
				Log.WriteError("r6ue75tddrthsdrftgsert", ex, "list title: " + title);
				newList = null;
			}
			return newList;
		}

		public static void CreateTaskList(SPWeb web, string title, string description, bool isDeleteIfListAlreadyExists)
		{
			try
			{
				// init
				if (web == null) { throw new Exception("SPWeb passed is null"); }
				if (string.IsNullOrEmpty(title)) { throw new Exception("Title passed is null"); }


				// create new list
				SPList newList = CreateList(web, title, description, SPListTemplateType.Tasks, false, false, false, false, isDeleteIfListAlreadyExists);

			}
			catch (Exception ex)
			{
				Log.WriteError("6usrttsrdsdgrs6tufdj", ex);
			}
		}

		/// <summary>
		/// Add content type(s) to passed list
		/// http://blogs.msdn.com/b/chandru/archive/2008/08/25/content-type-setting-up-default-content-type-programmatically.aspx
		/// </summary>
		/// <param name="list"></param>
		/// <param name="contentTypesToAdd"></param>
		/// <param name="defaultContentType">The default content type for this list.</param>
		/// <param name="isRemoveAllExistingContentTypes"></param>
		public static bool AddContentType(SPList list, List<SPContentType> contentTypesToAdd, SPContentType defaultContentType, 
			bool isRemoveAllExistingContentTypes)
		{
			bool isSuccessful = false;
			try
			{
				// init
				if (list == null) { throw new Exception("No list passed to add content types to"); }
				if (contentTypesToAdd == null || contentTypesToAdd.Count == 0) { throw new Exception("No content types passed to add to list"); }
				if (isRemoveAllExistingContentTypes)
				{
					if (contentTypesToAdd.Count == 1 && defaultContentType == null) { defaultContentType = contentTypesToAdd[0]; }
					if (defaultContentType == null) { throw new Exception("Must define default content type for list when removing the default content type"); }
				}


				// remove all existing content types?
				if (isRemoveAllExistingContentTypes)
				{
					for (int i = 0; i < list.ContentTypes.Count; i++)
					{
						list.ContentTypes.Delete(list.ContentTypes[i].Id);
						i--;
					}
				}

				// add content type(s)
				foreach (SPContentType contentType in contentTypesToAdd)
				{
					bool isMatch = false;
					foreach (SPContentType existingContentType in list.ContentTypes)
					{
						if (contentType == existingContentType)
						{
							isMatch = true;
							break;
						}
					}
					if (!isMatch)
					{
						// add content type
						list.ContentTypes.Add(contentType);
					}
				}

				// set default content type
				if (defaultContentType != null)
				{
					List<SPContentType> order = new List<SPContentType>();
					order.Add(defaultContentType);
					list.RootFolder.UniqueContentTypeOrder = order;
				}

				// update list
				list.RootFolder.Update();

				// assume success
				isSuccessful = true;
			}
			catch (Exception ex)
			{
				Log.WriteError("rt6GGitgydfgcdre", ex);
				isSuccessful = false;
			}
			return isSuccessful;
		}

		/// <summary>
		/// Add content type to passed list
		/// </summary>
		/// <param name="list"></param>
		/// <param name="contentType"></param>
		/// <param name="isMakeDefaultContentType"></param>
		/// <param name="isRemoveAllExistingContentTypes"></param>
		/// <returns></returns>
		public static bool AddContentType(SPList list, SPContentType contentType, bool isMakeDefaultContentType,
			bool isRemoveAllExistingContentTypes)
		{
			// make list of content types using the one content type passed
			List<SPContentType> contentTypes = new List<SPContentType>();
			contentTypes.Add(contentType);

			// set this content type as default
			SPContentType defaultContentType = null;
			if (isMakeDefaultContentType) { defaultContentType = contentType; }
			return AddContentType(list, contentTypes, defaultContentType, isRemoveAllExistingContentTypes);
		}

		


		/// <summary>
		/// 
		/// </summary>
		/// <param name="list"></param>
		/// <param name="viewTitle"></param>
		/// <param name="fieldsToAdd">A collection of field DISPLAY NAMES to add to the view</param>
		/// <param name="query"></param>
		/// <param name="isPaginated"></param>
		/// <param name="isDefaultView"></param>
		/// <param name="viewType"></param>
		/// <returns></returns>
		public static SPView CreateView(SPList list, string viewTitle, System.Collections.Specialized.StringCollection fieldsToAdd, string query,
			bool isPaginated, bool isDefaultView, SPViewCollection.SPViewType viewType)
		{
			SPView view = null;
			try
			{
				// init
				if (list == null) { throw new Exception("SPList passed is null"); }
				if (string.IsNullOrEmpty(viewTitle)) { viewTitle = list.DefaultView.Title; }

				// create view
				view = list.Views.Add(viewTitle, fieldsToAdd, query, 100, isPaginated, isDefaultView, viewType, false);

				// update list
				list.Update();
			}
			catch (Exception ex)
			{
				Log.WriteError("yhr56ujdsfge4yt", ex);
			}
			return view;
		}



		/// <summary>
		/// Get list url for passed list (no trailing slash)
		/// </summary>
		/// <param name="list"></param>
		/// <returns></returns>
		public static string GetUrl(SPList list, bool isAbsoluteUrl)
		{
			string url = null;
			if (list != null)
			{
				// list url (includes web url)
				string listUrl = list.DefaultViewUrl;
				
				// format list url, removing view filename, forms folder, and trailing slash
				listUrl = listUrl.Substring(0, listUrl.LastIndexOf("/"));
				if (listUrl.Length > 5 && listUrl.Substring(listUrl.Length - 5).ToLower() == "forms") 
				{ 
					listUrl = listUrl.Substring(0, (listUrl.Length - 5)); 
				}
				if (listUrl.Substring(listUrl.Length - 1) == "/") { listUrl = listUrl.Substring(0, listUrl.Length - 1); }

				// get url
				if (!isAbsoluteUrl) { url = listUrl; }
				else
				{
					// get site url
					string siteUrl = Site.GetUrl(list.ParentWeb.Site);

					// combine site url + list url
					if (listUrl == "/") { url = siteUrl; } else { url = siteUrl + listUrl; }
				}
			}
			return url;
		}
		/// <summary>
		/// get list url 
		/// </summary>
		/// <param name="list"></param>
		/// <returns></returns>
		public static string GetUrl(SPList list)
		{
			return GetUrl(list, false);
		}


		/// <summary>
		/// Delete all items in passed list, using bulk delete
		/// Does not delete checked out items
		/// </summary>
		/// <param name="list"></param>
		/// <param name="isDisableRecycleBin"></param>
		/// <returns></returns>
		public static bool DeleteAllItems(SPList list, bool isDisableRecycleBin)
		{
			// call original
			return Item.DeleteAllItems(list, isDisableRecycleBin);
		}



		/// <summary>
		/// Determine if passed list requires checkout/in
		/// </summary>
		/// <param name="list"></param>
		/// <returns></returns>
		public static bool IsCheckInOutRequired(SPList list)
		{
			bool isRequired = false;
			if (list != null && list.ForceCheckout)
			{
				isRequired = true;
			}
			return isRequired;
		}

		/// <summary>
		/// Determine if passed list requires publishing (minor versions)
		/// </summary>
		/// <param name="list"></param>
		/// <returns></returns>
		public static bool IsPublishRequired(SPList list)
		{
			bool isRequired = false;
			if (list != null && list.EnableMinorVersions)
			{
				isRequired = true;
			}
			return isRequired;
		}

		/// <summary>
		/// Determine if passed list required approval for items
		/// </summary>
		/// <param name="list"></param>
		/// <returns></returns>
		public static bool IsApprovalRequired(SPList list)
		{
			bool isRequired = false;
			if (list != null && list.EnableModeration)
			{
				isRequired = true;
			}
			return isRequired;
		}



    } // List Class

} // SPHelper namespace
